From 5217c075e8e0a01118517c59cdfe20e481825778 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 1 Apr 2008 09:42:52 -0600 Subject: [PATCH] [IA64] Use ppn to store io type. Instead of using 3 extra bits in pte to store the io type, only one bit is used to mark the page as an IO page and the type is stored in the ppn field. This both save 2 bits and allow many more io types. Move the VTi memory map to arch-ia64/hvm/memmap.h Signed-off-by: Tristan Gingold --- xen/arch/ia64/vmx/mmio.c | 17 ++-- xen/arch/ia64/vmx/sioemu.c | 7 +- xen/arch/ia64/vmx/vlsapic.c | 1 + xen/arch/ia64/vmx/vmmu.c | 2 +- xen/arch/ia64/vmx/vmx_fault.c | 10 ++- xen/arch/ia64/vmx/vmx_init.c | 13 +-- xen/arch/ia64/vmx/vtlb.c | 2 +- xen/arch/ia64/xen/mm.c | 3 +- xen/include/asm-ia64/linux-xen/asm/pgtable.h | 16 +--- xen/include/asm-ia64/vmmu.h | 2 +- xen/include/public/arch-ia64.h | 59 +++---------- xen/include/public/arch-ia64/hvm/memmap.h | 88 ++++++++++++++++++++ 12 files changed, 133 insertions(+), 87 deletions(-) create mode 100644 xen/include/public/arch-ia64/hvm/memmap.h diff --git a/xen/arch/ia64/vmx/mmio.c b/xen/arch/ia64/vmx/mmio.c index 44c5461310..067c4836b4 100644 --- a/xen/arch/ia64/vmx/mmio.c +++ b/xen/arch/ia64/vmx/mmio.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -352,11 +353,9 @@ static void legacy_io_access(VCPU *vcpu, u64 pa, u64 *val, size_t s, int dir) return; } -static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir, u64 pte) +static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int dir, u64 iot) { - unsigned long iot = pte & GPFN_IO_MASK; - - perfc_incra(vmx_mmio_access, iot >> 56); + perfc_incra(vmx_mmio_access, iot & 0x7); switch (iot) { case GPFN_PIB: if (ma != 4) @@ -367,8 +366,6 @@ static void mmio_access(VCPU *vcpu, u64 src_pa, u64 *dest, size_t s, int ma, int else *dest = vlsapic_read(vcpu, src_pa, s); break; - case GPFN_GFW: - break; case GPFN_IOSAPIC: if (!dir) viosapic_write(vcpu, src_pa, s, *dest); @@ -394,7 +391,7 @@ enum inst_type_en { SL_INTEGER, SL_FLOATING, SL_FLOATING_FP8 }; /* dir 1: read 0:write */ -void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 pte) +void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 iot) { REGS *regs; IA64_BUNDLE bundle; @@ -536,8 +533,6 @@ void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 pte) } if (vcpu->domain->arch.is_sioemu) { - unsigned long iot = pte & GPFN_IO_MASK; - if (iot != GPFN_PIB && iot != GPFN_IOSAPIC) { sioemu_io_emulate(padr, data, data1, update_word); return; @@ -545,10 +540,10 @@ void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma, u64 pte) } if (size == 4) { - mmio_access(vcpu, padr + 8, &data1, 1 << 3, ma, dir, pte); + mmio_access(vcpu, padr + 8, &data1, 1 << 3, ma, dir, iot); size = 3; } - mmio_access(vcpu, padr, &data, 1 << size, ma, dir, pte); + mmio_access(vcpu, padr, &data, 1 << size, ma, dir, iot); emulate_io_update(vcpu, update_word, data, data1); } diff --git a/xen/arch/ia64/vmx/sioemu.c b/xen/arch/ia64/vmx/sioemu.c index dad0d414fa..526d8c087f 100644 --- a/xen/arch/ia64/vmx/sioemu.c +++ b/xen/arch/ia64/vmx/sioemu.c @@ -166,8 +166,11 @@ sioemu_add_io_physmap (struct domain *d, unsigned long start, unsigned long i; int res; + /* Convert to ppn. */ + type <<= PAGE_SHIFT; + /* Check type. */ - if (type == 0 || (type & GPFN_IO_MASK) != type) + if (type == 0 || (type & _PAGE_PPN_MASK) != type) return -EINVAL; if ((start & (PAGE_SIZE -1)) || (size & (PAGE_SIZE - 1))) return -EINVAL; @@ -180,7 +183,7 @@ sioemu_add_io_physmap (struct domain *d, unsigned long start, /* Set. */ for (i = start; i < start + size; i += PAGE_SIZE) { - res = __assign_domain_page(d, i, type, ASSIGN_writable); + res = __assign_domain_page(d, i, type, ASSIGN_writable | ASSIGN_io); if (res != 0) return res; } diff --git a/xen/arch/ia64/vmx/vlsapic.c b/xen/arch/ia64/vmx/vlsapic.c index d6a1806840..124b4e892b 100644 --- a/xen/arch/ia64/vmx/vlsapic.c +++ b/xen/arch/ia64/vmx/vlsapic.c @@ -47,6 +47,7 @@ #include #include #include +#include #ifdef IPI_DEBUG #define IPI_DPRINTK(x...) printk(x) diff --git a/xen/arch/ia64/vmx/vmmu.c b/xen/arch/ia64/vmx/vmmu.c index 851fd5bded..4fb9593c05 100644 --- a/xen/arch/ia64/vmx/vmmu.c +++ b/xen/arch/ia64/vmx/vmmu.c @@ -314,7 +314,7 @@ IA64FAULT vmx_vcpu_itr_d(VCPU *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa) thash_purge_entries(vcpu, va, ps); gpfn = (pte & _PAGE_PPN_MASK)>> PAGE_SHIFT; gpte = lookup_domain_mpa(vcpu->domain, gpfn, NULL); - if (gpte & GPFN_IO_MASK) + if (gpte & _PAGE_IO) pte |= VTLB_PTE_IO; vcpu_get_rr(vcpu, va, &rid); rid &= RR_RID_MASK; diff --git a/xen/arch/ia64/vmx/vmx_fault.c b/xen/arch/ia64/vmx/vmx_fault.c index cbfea2a614..5a6ed0a163 100644 --- a/xen/arch/ia64/vmx/vmx_fault.c +++ b/xen/arch/ia64/vmx/vmx_fault.c @@ -372,8 +372,9 @@ vmx_hpw_miss(u64 vadr, u64 vec, REGS* regs) return IA64_FAULT; } pte = lookup_domain_mpa(v->domain, pa_clear_uc(vadr), NULL); - if (v->domain != dom0 && (pte & GPFN_IO_MASK)) { - emulate_io_inst(v, pa_clear_uc(vadr), 4, pte); + if (v->domain != dom0 && (pte & _PAGE_IO)) { + emulate_io_inst(v, pa_clear_uc(vadr), 4, + (pte & _PFN_MASK) >> PAGE_SHIFT); return IA64_FAULT; } physical_tlb_miss(v, vadr, type); @@ -404,12 +405,13 @@ try_again: } gppa = thash_translate(data, vadr); pte = lookup_domain_mpa(v->domain, gppa, NULL); - if (pte & GPFN_IO_MASK) { + if (pte & _PAGE_IO) { if (misr.sp) panic_domain(NULL, "ld.s on I/O page not with UC attr." " pte=0x%lx\n", data->page_flags); if (data->pl >= ((regs->cr_ipsr >> IA64_PSR_CPL0_BIT) & 3)) - emulate_io_inst(v, gppa, data->ma, pte); + emulate_io_inst(v, gppa, data->ma, + (pte & _PFN_MASK) >> PAGE_SHIFT); else { vcpu_set_isr(v, misr.val); data_access_rights(v, vadr); diff --git a/xen/arch/ia64/vmx/vmx_init.c b/xen/arch/ia64/vmx/vmx_init.c index 6a1c014c43..5f24e08e87 100644 --- a/xen/arch/ia64/vmx/vmx_init.c +++ b/xen/arch/ia64/vmx/vmx_init.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -553,11 +554,11 @@ typedef struct io_range { } io_range_t; static const io_range_t io_ranges[] = { - {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER}, - {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO}, - {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO}, - {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC}, - {PIB_START, PIB_SIZE, GPFN_PIB}, + {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER << PAGE_SHIFT}, + {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO << PAGE_SHIFT}, + {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO << PAGE_SHIFT}, + {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC << PAGE_SHIFT}, + {PIB_START, PIB_SIZE, GPFN_PIB << PAGE_SHIFT}, }; // The P2M table is built in libxc/ia64/xc_ia64_hvm_build.c @ setup_guest() @@ -571,7 +572,7 @@ static void vmx_build_io_physmap_table(struct domain *d) for (j = io_ranges[i].start; j < io_ranges[i].start + io_ranges[i].size; j += PAGE_SIZE) (void)__assign_domain_page(d, j, io_ranges[i].type, - ASSIGN_writable); + ASSIGN_writable | ASSIGN_io); } } diff --git a/xen/arch/ia64/vmx/vtlb.c b/xen/arch/ia64/vmx/vtlb.c index f956b68898..b1d5e25f46 100644 --- a/xen/arch/ia64/vmx/vtlb.c +++ b/xen/arch/ia64/vmx/vtlb.c @@ -515,7 +515,7 @@ static u64 translate_phy_pte(VCPU *v, u64 pte, u64 itir, u64 va) phy_pte.val = pte; paddr = ((pte & _PAGE_PPN_MASK) & ps_mask) | (va & ~ps_mask); maddr = lookup_domain_mpa(d, paddr, NULL); - if (maddr & GPFN_IO_MASK) + if (maddr & _PAGE_IO) return -1; /* Ensure WB attribute if pte is related to a normal mem page, diff --git a/xen/arch/ia64/xen/mm.c b/xen/arch/ia64/xen/mm.c index 4f880a7ca1..d51912fc21 100644 --- a/xen/arch/ia64/xen/mm.c +++ b/xen/arch/ia64/xen/mm.c @@ -886,6 +886,7 @@ flags_to_prot (unsigned long flags) res |= flags & ASSIGN_tlb_track ? _PAGE_TLB_TRACKING: 0; #endif res |= flags & ASSIGN_pgc_allocated ? _PAGE_PGC_ALLOCATED: 0; + res |= flags & ASSIGN_io ? _PAGE_IO: 0; return res; } @@ -966,7 +967,7 @@ assign_domain_page(struct domain *d, { struct page_info* page = mfn_to_page(physaddr >> PAGE_SHIFT); - BUG_ON((physaddr & GPFN_IO_MASK) != GPFN_MEM); + BUG_ON((physaddr & _PAGE_PPN_MASK) != physaddr); BUG_ON(page->count_info != (PGC_allocated | 1)); set_gpfn_from_mfn(physaddr >> PAGE_SHIFT, mpaddr >> PAGE_SHIFT); // because __assign_domain_page() uses set_pte_rel() which has diff --git a/xen/include/asm-ia64/linux-xen/asm/pgtable.h b/xen/include/asm-ia64/linux-xen/asm/pgtable.h index c8f2dbebf9..2bc246726e 100644 --- a/xen/include/asm-ia64/linux-xen/asm/pgtable.h +++ b/xen/include/asm-ia64/linux-xen/asm/pgtable.h @@ -97,17 +97,9 @@ #define _PAGE_PGC_ALLOCATED_BIT 59 /* _PGC_allocated */ #define _PAGE_PGC_ALLOCATED (__IA64_UL(1) << _PAGE_PGC_ALLOCATED_BIT) -/* domVTI */ -#define GPFN_MEM (0UL << 60) /* Guest pfn is normal mem */ -#define GPFN_FRAME_BUFFER (1UL << 60) /* VGA framebuffer */ -#define GPFN_LOW_MMIO (2UL << 60) /* Low MMIO range */ -#define GPFN_PIB (3UL << 60) /* PIB base */ -#define GPFN_IOSAPIC (4UL << 60) /* IOSAPIC base */ -#define GPFN_LEGACY_IO (5UL << 60) /* Legacy I/O base */ -#define GPFN_GFW (6UL << 60) /* Guest Firmware */ -#define GPFN_HIGH_MMIO (7UL << 60) /* High MMIO range */ - -#define GPFN_IO_MASK (7UL << 60) /* Guest pfn is I/O type */ + +#define _PAGE_IO_BIT 60 +#define _PAGE_IO (__IA64_UL(1) << _PAGE_IO_BIT) #else #define _PAGE_PROTNONE (__IA64_UL(1) << 63) @@ -341,7 +333,7 @@ set_pte_rel(volatile pte_t* ptep, pte_t pteval) #define pte_file(pte) ((pte_val(pte) & _PAGE_FILE) != 0) #ifdef XEN #define pte_pgc_allocated(pte) ((pte_val(pte) & _PAGE_PGC_ALLOCATED) != 0) -#define pte_mem(pte) (!(pte_val(pte) & GPFN_IO_MASK) && !pte_none(pte)) +#define pte_mem(pte) (!(pte_val(pte) & _PAGE_IO) && !pte_none(pte)) #endif /* * Note: we convert AR_RWX to AR_RX and AR_RW to AR_R by clearing the 2nd bit in the diff --git a/xen/include/asm-ia64/vmmu.h b/xen/include/asm-ia64/vmmu.h index ff26ad4eb4..90d06c90b8 100644 --- a/xen/include/asm-ia64/vmmu.h +++ b/xen/include/asm-ia64/vmmu.h @@ -190,7 +190,7 @@ extern int init_domain_tlb(struct vcpu *v); extern void free_domain_tlb(struct vcpu *v); extern thash_data_t * vhpt_lookup(u64 va); extern unsigned long fetch_code(struct vcpu *vcpu, u64 gip, IA64_BUNDLE *pbundle); -extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma, u64 pte); +extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma, u64 iot); extern void emulate_io_update(struct vcpu *vcpu, u64 word, u64 d, u64 d1); extern int vhpt_enabled(struct vcpu *vcpu, uint64_t vadr, vhpt_ref_t ref); extern void thash_vhpt_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa, diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index afb2a52164..76cb70fb1a 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -62,6 +62,10 @@ typedef unsigned long xen_pfn_t; /* WARNING: before changing this, check that shared_info fits on a page */ #define MAX_VIRT_CPUS 64 +/* IO ports location for PV. */ +#define IO_PORTS_PADDR 0x00000ffffc000000UL +#define IO_PORTS_SIZE 0x0000000004000000UL + #ifndef __ASSEMBLY__ #define __anonymous_union __extension__ union @@ -76,54 +80,6 @@ typedef unsigned long xen_ulong_t; #define INVALID_MFN (~0UL) -#define MEM_G (1UL << 30) -#define MEM_M (1UL << 20) -#define MEM_K (1UL << 10) - -/* Guest physical address of IO ports space. */ -#define IO_PORTS_PADDR 0x00000ffffc000000UL -#define IO_PORTS_SIZE 0x0000000004000000UL - -#define MMIO_START (3 * MEM_G) -#define MMIO_SIZE (512 * MEM_M) - -#define VGA_IO_START 0xA0000UL -#define VGA_IO_SIZE 0x20000 - -#define LEGACY_IO_START (MMIO_START + MMIO_SIZE) -#define LEGACY_IO_SIZE (64*MEM_M) - -#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE) -#define IO_PAGE_SIZE XEN_PAGE_SIZE - -#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE) -#define STORE_PAGE_SIZE XEN_PAGE_SIZE - -#define BUFFER_IO_PAGE_START (STORE_PAGE_START + STORE_PAGE_SIZE) -#define BUFFER_IO_PAGE_SIZE XEN_PAGE_SIZE - -#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE) -#define BUFFER_PIO_PAGE_SIZE XEN_PAGE_SIZE - -#define IO_SAPIC_START 0xfec00000UL -#define IO_SAPIC_SIZE 0x100000 - -#define PIB_START 0xfee00000UL -#define PIB_SIZE 0x200000 - -#define GFW_START (4*MEM_G -16*MEM_M) -#define GFW_SIZE (16*MEM_M) - -/* Nvram belongs to GFW memory space */ -#define NVRAM_SIZE (MEM_K * 64) -#define NVRAM_START (GFW_START + 10 * MEM_M) - -#define NVRAM_VALID_SIG 0x4650494e45584948 // "HIXENIPF" -struct nvram_save_addr { - unsigned long addr; - unsigned long signature; -}; - struct pt_fpreg { union { unsigned long bits[2]; @@ -505,6 +461,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); /* Internal only: associated with PGC_allocated bit */ #define _ASSIGN_pgc_allocated 3 #define ASSIGN_pgc_allocated (1UL << _ASSIGN_pgc_allocated) +/* Page is an IO page. */ +#define _ASSIGN_io 4 +#define ASSIGN_io (1UL << _ASSIGN_io) /* This structure has the same layout of struct ia64_boot_param, defined in . It is redefined here to ease use. */ @@ -640,6 +599,10 @@ DEFINE_XEN_GUEST_HANDLE(pfarg_load_t); #endif /* __ASSEMBLY__ */ #endif /* XEN */ +#ifndef __ASSEMBLY__ +#include "arch-ia64/hvm/memmap.h" +#endif + #endif /* __HYPERVISOR_IF_IA64_H__ */ /* diff --git a/xen/include/public/arch-ia64/hvm/memmap.h b/xen/include/public/arch-ia64/hvm/memmap.h new file mode 100644 index 0000000000..10054b2577 --- /dev/null +++ b/xen/include/public/arch-ia64/hvm/memmap.h @@ -0,0 +1,88 @@ +/****************************************************************************** + * memmap.h + * + * Copyright (c) 2008 Tristan Gingold + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __XEN_PUBLIC_HVM_MEMMAP_IA64_H__ +#define __XEN_PUBLIC_HVM_MEMMAP_IA64_H__ + +#define MEM_G (1UL << 30) +#define MEM_M (1UL << 20) +#define MEM_K (1UL << 10) + +/* Guest physical address of IO ports space. */ +#define MMIO_START (3 * MEM_G) +#define MMIO_SIZE (512 * MEM_M) + +#define VGA_IO_START 0xA0000UL +#define VGA_IO_SIZE 0x20000 + +#define LEGACY_IO_START (MMIO_START + MMIO_SIZE) +#define LEGACY_IO_SIZE (64 * MEM_M) + +#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE) +#define IO_PAGE_SIZE XEN_PAGE_SIZE + +#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE) +#define STORE_PAGE_SIZE XEN_PAGE_SIZE + +#define BUFFER_IO_PAGE_START (STORE_PAGE_START + STORE_PAGE_SIZE) +#define BUFFER_IO_PAGE_SIZE XEN_PAGE_SIZE + +#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE) +#define BUFFER_PIO_PAGE_SIZE XEN_PAGE_SIZE + +#define IO_SAPIC_START 0xfec00000UL +#define IO_SAPIC_SIZE 0x100000 + +#define PIB_START 0xfee00000UL +#define PIB_SIZE 0x200000 + +#define GFW_START (4 * MEM_G - 16 * MEM_M) +#define GFW_SIZE (16 * MEM_M) + +/* domVTI */ +#define GPFN_FRAME_BUFFER 0x1 /* VGA framebuffer */ +#define GPFN_LOW_MMIO 0x2 /* Low MMIO range */ +#define GPFN_PIB 0x3 /* PIB base */ +#define GPFN_IOSAPIC 0x4 /* IOSAPIC base */ +#define GPFN_LEGACY_IO 0x5 /* Legacy I/O base */ +#define GPFN_HIGH_MMIO 0x6 /* High MMIO range */ + +/* Nvram belongs to GFW memory space */ +#define NVRAM_SIZE (MEM_K * 64) +#define NVRAM_START (GFW_START + 10 * MEM_M) + +#define NVRAM_VALID_SIG 0x4650494e45584948 /* "HIXENIPF" */ +struct nvram_save_addr { + unsigned long addr; + unsigned long signature; +}; + +#endif /* __XEN_PUBLIC_HVM_MEMMAP_IA64_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ -- 2.30.2